package io.plus.server.command.command_handler.auth;

import io.plus.common.io;
import io.plus.common.packet.Group;
import io.plus.common.packet.User;
import io.plus.common.packet.auth.LoginRequestMessage;
import io.plus.common.packet.auth.LoginResponseMessage;
import io.plus.common.packet.metadata.Command;
import io.plus.common.protocol.Packet;
import io.plus.engine.pulse.AsynchronousSocketChannelContext;
import io.plus.engine.pulse.Io;
import io.plus.server.SessionContext;
import io.plus.server.Status;
import io.plus.server.UserConfiguration;
import io.plus.server.command.CommandHandler;
import io.plus.server.command.CommandManager;
import io.plus.server.command.command_handler.group.JoinGroupCommandHandler;
import io.plus.server.store.Store;
import io.plus.server.store.StoreImpl;
import io.plus.server.utils.JsonKit;
import lombok.extern.slf4j.Slf4j;
import tool.plus.$;
import tool.plus.Uuid;

import java.util.List;


/**
 * 登录消息命令处理器
 */
@Slf4j
public class LoginCommandHandler implements CommandHandler {

    /**
     * 初始化绑定或者解绑群组;
     */
    public void bindUnbindGroup(UserConfiguration userConfiguration, AsynchronousSocketChannelContext asynchronousSocketChannelContext, User user) throws Exception {
        String userId = user.getId();
        List<Group> groups = user.getGroups();
        if (groups != null) {
            boolean isStore = true;
            Store store = null;
            List<String> groupIds = null;
            if (isStore) {
                store = userConfiguration.getStore();
                groupIds = store.getGroupIdList(userId);
            }
            //绑定群组
            for (Group group : groups) {
                if (isStore && groupIds != null) {
                    groupIds.remove(group.getId());
                }
                Packet groupPacket = new Packet(Command.join_group_request, Status.ok, JsonKit.toJsonBytes(group));
                try {
                    JoinGroupCommandHandler joinGroupReqHandler = CommandManager.getCommand(Command.join_group_request, JoinGroupCommandHandler.class);
                    joinGroupReqHandler.bindGroup(userConfiguration, groupPacket, asynchronousSocketChannelContext);
                } catch (Exception e) {
                    log.error(e.toString(), e);
                }
            }
            if (isStore && groupIds != null) {
                for (String groupId : groupIds) {

                }
            }
        }
    }

    @Override
    public Command command() {
        return Command.login_request;
    }

    @Override
    public Packet handler(UserConfiguration userConfiguration, AsynchronousSocketChannelContext asynchronousSocketChannelContext, Packet packet) throws Exception {
        if (packet.getBody() == null) {
            Io.remove(asynchronousSocketChannelContext, "body is null");
            return null;
        }


        LoginRequestMessage loginRequestMessage = JsonKit.toBean(packet.getBody(), LoginRequestMessage.class);

        String loginname = loginRequestMessage.getLoginname();
        String password = loginRequestMessage.getPassword();
        SessionContext sessionContext = (SessionContext) asynchronousSocketChannelContext.getAttribute();
        String token = sessionContext.getToken();
        User user;
        LoginResponseMessage loginResponseMessage;
        if (!$.isNullOrEmpty((token))) {
            user = ((StoreImpl) userConfiguration.getStore()).tokenToUserMap.get(token);
            if (user == null) {
                user = new User();
                user.setId(token);
                ((StoreImpl) userConfiguration.getStore()).tokenToUserMap.put(token, user);
            }
        } else {
            token = Uuid.uuid();
            user = new User();
            user.setId(token);
            ((StoreImpl) userConfiguration.getStore()).tokenToUserMap.put(token, user);
        }
        if (user == null) {
            loginResponseMessage = new LoginResponseMessage(Command.login_respnse, Status.login_failed);
        } else {
            loginResponseMessage = new LoginResponseMessage(Command.login_respnse, Status.login_succeed, null, user);
        }
        if (loginResponseMessage == null || loginResponseMessage.getUser() == null) {
            log.info("登录失败, loginName:{}, password:{}", loginRequestMessage.getLoginname(), loginRequestMessage.getPassword());
            if (loginResponseMessage == null) {
                loginResponseMessage = new LoginResponseMessage(Command.login_respnse, Status.login_failed);
            }

            Packet loginRespPacket = new Packet(Command.login_respnse, Status.ok, loginResponseMessage.toByte());
            io.bSend(asynchronousSocketChannelContext, loginRespPacket);
            io.remove(asynchronousSocketChannelContext, "loginName and token is incorrect");
            return null;
        }

        String userId = user.getId();


        sessionContext.getClient().setUser(user);
        io.bindUser(asynchronousSocketChannelContext, userId);
        //初始化绑定或者解绑群组;
        bindUnbindGroup(userConfiguration, asynchronousSocketChannelContext, user);


        Packet loginRespPacket = new Packet(Command.login_respnse, Status.ok, loginResponseMessage.toByte());
        return loginRespPacket;
    }
}
